/**************************************************************

Project:     L-Spider
Module:      L-Web-Scale
Description: Action device harness control

MCU: PIC16F628A
Clock: Internal (48kHz)

Config word:
       - Watchdog Timer:   Disabled
       - Power-On Reset:   Enabled
       - Master Clear:     Disabled
       - Brown-out Detect: Disabled
       - Low Voltage Prog: Disabled
       - Data EE Protect:  Disabled
       - Oscillator:       INTOSC
       
***************************************************************/

// Constants


//----------------------------------------------------------------

// Global identifiers

unsigned int n_alarms;

//*****************************************************************

void mcu_initialize() {

    // Initialize peripherals

    T1CON = 0b00110000;   // Shut off TMR1; internal clock, set prescaler to 1:8
    T2CON = 0b00000011;   // Shut off TMR2; set prescaler to 1:16
    
    CCP1CON = 0;          // Shut off CCP/PWM
    RCSTA = 0;            // Disable USART

    CMCON = 0b00000111;   // Shut comparators off, tie their inputs to GND
                        
    VRCON = 0;            // Shut reference voltage circuit off
    
    PCON  = 0b00000000;      // Set internal oscillator frequency to low (48 kHz)
    INTCON = 0b00000000;     // Disable
    PIE1 = 0;                //    all interrupts
    OPTION_REG = 0b00000000; // Enable PORTB weak pull-ups

    // Configure I/O ports

    TRISA = 0b11111111;  // PORTA is all inputs (not used, to reduce consumption)
    TRISB = 0b00001111;  // Output: RB7:4 (SS relays)
                         //   Input: RB3:0 (only RB0 actually used)
                         
    PORTB = 0b11111111;  // Everything is active low; switch everything off

} // mcu_initialize()

//========================================================

unsigned char incoming_event() {
    return ~( ( PORTB & 0b00000001 ) | 0b11111110);  // If bit RB0 is 0 (active), will return 1
} // incoming_event()

//========================================================

void device_activate( unsigned char device_number ) {
    switch( device_number ) {
        case 1: PORTB &= 0b01111111;
                break;
        case 2: PORTB &= 0b10111111;
                break;
        case 3: PORTB &= 0b11011111;
                break;
        case 4: PORTB &= 0b11101111;
                break;
        case 0: PORTB &= 0b00001111;  // Device number of 0 will activate all devices
                break;
    } // switch device_number
} // device_activate()

//========================================================

void device_deactivate( unsigned char device_number ) {
    switch( device_number ) {
        case 1: PORTB |= 0b10000000;
                break;
        case 2: PORTB |= 0b01000000;
                break;
        case 3: PORTB |= 0b00100000;
                break;
        case 4: PORTB |= 0b00010000;
                break;
        case 0: PORTB |= 0b11110000;  // Device number of 0 will deactivate all devices
                break;
    } // switch device_number
} // device_deactivate()

//*****************************************************************

void main() {

    mcu_initialize(); // Initialize MCU
    
    n_alarms = 0;
    device_deactivate( 0 );  // Deactivate all devices

//========================================================

    // Main working cycle

    while( 1 ) {

        if ( incoming_event() ) {            //  On every alarm
            if ( ++n_alarms > 4 )            //  Increment number of alarms
                n_alarms = 1;                //    and if it exceeds 4, start over again
                
            Delay_ms( 1000 );                //  Wait a little bit
            device_activate( n_alarms );     //    then react
            Delay_ms( 5000 );                //  Keep initiator on for 5 sec
            device_deactivate( n_alarms );   //    then disable it
            
            while ( incoming_event() ) {}    //  Wait until event ends
            Delay_ms( 20 );                  //  And ensure there's no tremble
            
        }  // if incoming_event
       
    } // while(1)
} // main()

// *** End of file ***
